/*
 * @Author: wangming
 * @Date: 2021-10-26 17:48:53
 * @LastEditors: wangming
 * @LastEditTime: 2022-05-26 15:52:02
 * @FilePath: /hanma-paas-mobile-fed/Users/wm/瀚川/hanma-application-designer-fed/src/utils/runFormatMap.js
 * @Description:  动态显示隐藏
 */
import storeform from "@/store";
import { getFunForJSON } from "./common.js";
const Rule = [
    {
        name: "=",
        callback: (v, rightVariableValue) => {
            return rightVariableValue == v;
        },
        value: "eq",
    },
    {
        name: "≠",
        callback: (v, rightVariableValue) => {
            return rightVariableValue != v;
        },
        value: "ne",
    },
    {
        name: ">",
        callback: (v, rightVariableValue) => {
            return rightVariableValue > v;
        },
        value: "gt",
    },
    {
        name: "≥",
        callback: (v, rightVariableValue) => {
            return rightVariableValue >= v;
        },
        value: "ge",
    },
    {
        name: "<",
        callback: (v, rightVariableValue) => {
            return rightVariableValue < v;
        },
        value: "lt",
    },
    {
        name: "≤",
        callback: (v, rightVariableValue) => {
            return rightVariableValue <= v;
        },
        value: "le",
    },
    {
        callback: (v, rightVariableValue) => {
            let rightV = rightVariableValue.match(/[\w\u4e00-\u9fa5]+/g) || []
            let value = (v || '').match(/[\w\u4e00-\u9fa5]+/g) || [null]
            return rightV.every(i => value.indexOf(i) > -1)
        },
        value: "similarTo",
    },
    {
        callback: (v, rightVariableValue) => {
            let rightV = rightVariableValue.match(/[\w\u4e00-\u9fa5]+/g) || []
            let value = (v || '').match(/[\w\u4e00-\u9fa5]+/g) || [null]
            return !rightV.every(i => value.indexOf(i) > -1)
        },
        value: "notSimilarTo",
    },
    {
        callback: (v, rightVariableValue) => {
            let [min, max] = rightVariableValue?.split(",") || [];
            return v >= min && v <= max;
        },
        value: "between",
    },
    {
        callback: (v, rightVariableValue) => {
            let [min, max] = rightVariableValue?.split(",") || [];
            return v < min || v > max;
        },
        value: "notBetween",
    },
    {
        callback: (v, rightVariableValue) => {
            return v.indexOf(rightVariableValue) > -1
        },
        value: "like",
    },
    {
        callback: (v, rightVariableValue) => {
            return v.indexOf(rightVariableValue) === -1
        },
        value: "notLike",
    },
    {
        callback: (v, rightVariableValue) => {
            return v === null || v === undefined || v === ''
        },
        value: "isNull",
    },
    {
        callback: (v, rightVariableValue) => {
            return v !== null && v !== undefined && v !== ''
        },
        value: "isNotNull",
    },

];



export default class RunFormat {
    /**
     * 确定依赖表单初始化函数
     * @param {*} config 
     * @param {*} vmEvents 
     * @param {*} callback 
     */
    static readyRunFormat(RuleConditions, vmEvents, callback) {
        let keysSet = new Set();
        RuleConditions.forEach((i) => {
            if (i.ruletype === "js") {
                i.jsRuleForm.forEach((r) => {
                    /^layoutform_.*/.test(r.formkey) && keysSet.add(r.formkey);
                });
            } else if (/^layoutform_.*/.test(i.formkey)) {
                //选择自身key后不需要等待
                keysSet.add(i.formkey);
            }
        });
        vmEvents.readyComponent({ keys: [...keysSet] }).then(callback);
    }
    /**
     * 执行自定义函数
     * @param {*} forms 
     * @param {*} config 
     * @param {*} vmEvents 
     * @param {*} callback 
     */
    static runjsRule({ forms }, Rules, vmEvents, callback) {
        try {
            let { exports, context } = vmEvents
            let RuleConditions = Rules.filter(({ ruletype }) => ruletype === 'js')
            let PromiseAll = RuleConditions.map(async i => {
                let args = forms[i.name] || []
                let js = decodeURIComponent(i.customFun)
                let flag = await getFunForJSON(js, 'getRulefun')(context, exports, ...args)
                if (flag) {
                    return Promise.resolve()
                } else {
                    return Promise.reject()
                }
            })
            Promise.all(PromiseAll).then(() => callback(true), () => callback(false))
        } catch (error) {
            console.log(error)
        }

    }
    /**
     * 解析自定义函数关联的表单字段值
     * @param {*} config 
     * @returns 
     */
    static getjsRulekeys(Rules, vms, operateKey, formRow) {
        let RuleConditions = Rules.filter(({ ruletype }) => ruletype === 'js')
        let computedKey = RuleConditions.reduce((total, curr) => {
            total[curr.name] = curr.jsRuleForm.map((formcurr) => {
                let form = operateKey === formcurr.formkey ? formRow : vms[formcurr.formkey] || {}
                let formtotal = {}
                formcurr.formcode.forEach(i => {
                    formtotal[i] = form[i]
                })
                return formtotal
            })
            return total
        }, {})
        return computedKey
    }
    /**
     * 操作按钮处理
     * @param {*} Rules 
     * @param {*} operateKey 
     * @param {*} formRow 
     * @returns 
     */
    static initButton(Rules, vms, operateKey, formRow) {
        let RuleConditions = Rules.filter(({ ruletype }) => ruletype !== 'js')
        if (RuleConditions?.length > 0) {
            return RuleConditions.every(({ formatData, formkey }) => {
                let form = formkey === operateKey ? formRow : (vms[formkey] || {})
                return this.runFormatMap(formatData, form)
            })
        } else {
            return true
        }
    }
    /**
     * 普通按钮处理
     * @param {*} config 
     * @param {*} vms 
     * @returns 
     */
    static initShow(Rules, vms) {
        try {
            let RuleConditions = Rules.filter(({ ruletype }) => ruletype !== 'js')
            return this.getseniorShow(RuleConditions, vms)
        } catch (error) {
            console.log(error)
        }
    }
    /**
     * 通用组件或布局处理
     * @param {*} form 
     * @param {*} config 
     * @param {*} vms 
     * @returns 
     */
    static init(form, config, vms) {
        try {
            let Rules = config?.__highSetUp?.RuleConditions || [];
            let RuleConditions = Rules.filter(({ ruletype }) => ruletype !== 'js')
            return this.getOldShow(config, form) && this.getseniorShow(RuleConditions, vms)
        } catch (error) {
            console.log(error)
        }
    }
    /**
     * 兼容老版本的显示条件控制
     * @returns 
     */
    static getOldShow(config, form) {
        if (config.__highSetUp?.DisplayConditions?.length > 0) {
            let flag = config.__highSetUp.DisplayConditions.some((i) => {
                return i.rules.every((k) => {
                    return (form[k.modelName] == k.value) === k.checked;
                });
            });
            return flag;
        } else {
            return true;
        }
    }
    static getseniorShow(RuleConditions, vms) {
        return RuleConditions.every(({ formatData, formkey }) => {
            let form = vms[formkey] || []
            return this.runFormatMap(formatData, form)
        }
        );
    }
    static validateValue(values, form) {
        let { operator, leftVariable, rightVariable } = values;
        let { callback } = Rule.find((i) => i.value === operator);
        let ruleValue = rightVariable.value;
        if (leftVariable.type === "BOOL") {
            ruleValue = ruleValue === "TRUE";
        }
        if (rightVariable.type === "SYS_VAR") {
            let { id, name, orgId } = storeform.getters.getUserVal
            switch (ruleValue) {
                case 'U_NAME':
                    ruleValue = name
                    break;
                case 'U_ID':
                    ruleValue = `[${id}]`
                    break;
                case 'U_MAIN_DEPARTMENT':
                    ruleValue = `[${orgId}]`
                    break;
                default:
                    break;
            }
        }
        let formValue = form[leftVariable.value];
        return callback(formValue, ruleValue);
    }
    static runFormatMap(data, form) {
        if (!!data.rightVariable) {
            return this.validateValue(data, form);
        }
        if (data.logicType === "or") {
            return data.children.some((i) => this.runFormatMap(i, form));
        }
        if (data.logicType === "and") {
            return data.children.every((i) => this.runFormatMap(i, form));
        }
    }
}